function Fruit(name) { // 父类构造函数
    this.name = name;
    this.play = [1, 2, 3];
}
// 父类原型上定义方法
Fruit.prototype.intro = function(color) {
    console.log(this.name + ' is ' + color);
}

// 1. 原型链式继承
function Apple1(name) {}

Apple1.prototype = new Fruit();
// Apple.name = 'asdf' // 会报错
Apple1.prototype.name = 'apple'; // 只能继续在原型上添加参数

var s1 = new Apple1();
var s2 = new Apple1();

s1.play.push(4);
console.log(s1.play, s2.play); // [1,2,3,4] [1,2,3,4]

// console.log(s1);
// console.log(s1.prototype); 


// 2. 构造函数继承
function Apple2(name, color) {
    Fruit.call(this, name); // key
    this.name = name;
    this.color = color;
}
// 只能在自己的原型上定义函数，无法调用父类原型上的方法
// Apple2.prototype.intro = function () {
//     console.log("this", this);
// }

var apple2 = new Apple2('apple', 'red');
console.log(apple2.name); // apple
// apple2.intro() // 会报错


// 3. 实例继承
// 这种方式要调用两次new。通过生成一个新的父类对象并返回来实现继承
function Apple3(name, color) {
    var o = new Fruit(name);
    o.color = color;
    return o;
}
var apple3 = new Apple3('apple3', 'red');
var apple33 = new Apple3('apple33', 'red');
console.log(apple3);
console.log(apple33);
console.log(apple3.__proto__);
console.log(apple3.__proto__ === apple33.__proto__); // true


// 4. 组合继承（原型链继承 + 构造函数继承）
function Apple4(name, color) {
    Fruit.call(this, name);
    this.color = color;
}
Apple4.prototype = new Fruit();
Apple4.prototype.constructor = Apple4;
var apple4 = new Apple4('apple4', 'red');

console.log("apple4", apple4);


// 5. 寄生组合继承
function Apple5(name, color) {
    Fruit.call(this, name);
    this.color = color;
}
Apple5.prototype = Object.create(Fruit.prototype);
Apple5.prototype.constructor = Apple5;
var apple5 = new Apple5('apple5', 'red');
console.log("apple5", apple5); // apple5 Apple5 { name: 'apple5', play: [ 1, 2, 3 ], color: 'red' }
console.log(apple5 instanceof Apple5); // true
apple5.intro('red') // 父类原型的方法也可以调用

// 6. class继承

